<?php

namespace app\console\controller;

use mon\env\Config;
use mon\util\Instance;
use app\model\ChatWaiterModel;
use GatewayWorker\Lib\Gateway;
use app\model\ChatMessageModel;
use app\model\ChatMessageRelationModel;

/**
 * 客服接待链接服务
 */
class ReceptionController
{
    use Instance;

    /**
     * 需要验证登录的指令
     *
     * @var array
     */
    protected $loginType = ['send', 'close'];

    /**
     * 执行指令回调业务
     *
     * @param array $query 请求参数
     * @return void
     */
    public function handle($query, $client_id)
    {
        if (!isset($query['type'])) {
            return Gateway::sendToCurrentClient($this->result(420, 'cmd unrecognized'));
        }
        // 判断需要登录的请求
        if (in_array($query['type'], $this->loginType) && !isset($_SESSION['uid'])) {
            return Gateway::sendToCurrentClient($this->result(403, 'cmd unrecognized login'));
        }

        switch ($query['type']) {
            case 'ping':
                // 客户端心跳
                Gateway::sendToCurrentClient($this->result(200, 'pong'));
                break;
            case 'login':
                // 客户端创建通信
                $this->login($query, $client_id);
                break;
            case 'send':
                // 发送信息
                $this->send($query);
                break;
            case 'transfer':
                // 会话转移
                $this->transfer($query);
                break;
            case 'close':
                // 关闭连接
                $this->close($query);
                break;
        }
    }

    /**
     * 结束对话
     *
     * @param array $data
     * @return void
     */
    protected function close($data)
    {
        $result = [];
        $result['type'] = 'receptionExit';
        // 客服的标识uid
        $result['group'] = $_SESSION['uid'];
        $result['msg'] = '咨询服务已结束，感谢您的咨询';
        Gateway::sendToUid($data['to'], $this->result(200, 'success', $result));
        unset($result);
    }

    /**
     * 发送信息
     *
     * @param array $data
     * @return void
     */
    protected function send($data)
    {
        if (!isset($data['to']) || is_null($data['to']) || empty($data['to']) || !isset($data['app']) || empty($data['app'])) {
            return Gateway::sendToCurrentClient($this->result(404, 'params faild'));
        }
        $nowTime = time();
        $result = [];
        $result['type'] = $data['dataType'];
        $result['content'] = $data['content'];
        $result['from'] = $_SESSION['uid'];
        $result["time"] = $nowTime;
        // 发给访客
        Gateway::sendToUid($data['to'], $this->result(200, 'success', $result));
        // 发给客服
        $result['visitid'] = $data['to'];
        Gateway::sendToCurrentClient($this->result(200, 'success', $result));

        // Gateway::sendToCurrentClient($this->result(200, 'ok', [
        //     'type'      => 'card',
        //     'visitid'   => $data['to'],
        //     'from'      => $_SESSION['uid'],
        //     'img'       => 'https://z3.ax1x.com/2020/11/20/DQ1Tns.jpg',
        //     'title'     => '测试图文内容',
        //     'desc'      => '测试图文内容描述',
        //     'link'      =>  'http://baidu.com',
        //     'time'      => $nowTime
        // ]));

        unset($result);
        // 会话内容入库
        $chat_relation = ChatMessageRelationModel::instance()->record($data['app'], code2id($_SESSION['uid']), $data['to']);
        if ($chat_relation) {
            // 更新最后通信时间
            ChatMessageRelationModel::instance()->save(['near_time' => $nowTime], ['id' => $chat_relation]);
            $chat_content = json_encode(['type' => $data['dataType'], 'content' => $data['content'], 'from' => $_SESSION['uid'], 'to' => $data['to']], JSON_UNESCAPED_UNICODE);
            ChatMessageModel::instance()->record($chat_relation, $chat_content);
        }
    }

    /**
     * 客服人员登录
     *
     * @see {"type":"login", "uid":"客服标识", "app":"所属系统"}
     * @param array $data
     * @return void
     */
    protected function login($data, $client_id)
    {
        if (!isset($data['app']) || !is_array($data['app']) || !isset($data['uid']) || empty($data['uid'])) {
            return Gateway::sendToCurrentClient($this->result(404, 'params faild'));
        }
        if (empty($data['app'])) {
            return Gateway::sendToCurrentClient($this->result(201, '请先绑定应用'));
        }

        // 只允许通过验证链接的ticket用户登录
        if (Config::instance()->get('socket.safe.auth', true) && $data['uid'] != $_SESSION['ticket']) {
            return Gateway::sendToCurrentClient($this->result(401, 'not auth'));
        }

        // 获取用户信息
        $userInfo = ChatWaiterModel::instance()->getInfo(['id' => code2id($data['uid'])]);
        if (!$userInfo) {
            return Gateway::sendToCurrentClient($this->result(202, '获取用户信息失败，请刷新重新链接'));
        }

        // 用户信息
        $_SESSION['userInfo'] = $userInfo;
        unset($userInfo);
        // 个人标识ID
        $_SESSION['uid'] = $data['uid'];
        // 角色
        $_SESSION['role'] = 'reception';
        // 所属APP
        $_SESSION['app'] = $data['app'];
        // 空闲状态
        $_SESSION['state'] = "free";
        // $uid绑定
        Gateway::bindUid($client_id, $_SESSION['uid']);
        // 加入客服组
        foreach ($data['app'] as $app) {
            Gateway::joinGroup($client_id, "kf_" . $app);
        }

        // 查看当前客服对应的会话组是否有人
        if (Gateway::getClientIdCountByGroup($_SESSION['uid'])) {
            // 获取在线访客列表
            $client_id_session = Gateway::getClientSessionsByGroup($_SESSION['uid']);
            $client_uid_session = [];
            foreach ($client_id_session as $session) {
                if (!isset($client_uid_session[$session['uid']])) {
                    $client_uid_session[$session['uid']] = [
                        "ip"        => $session["ip"],
                        "id"        => $session["id"],
                        "app"       => $session["app"],
                        "app_title" => $session["app_title"],
                        'time'      => isset($session['last_send_time']) ? $session['last_send_time'] : ''
                    ];
                }
            }
            $list = [];
            // 处理数据
            $default_avatar = Config::instance()->get('chat.default_avatar');
            foreach ($client_uid_session as $visitorid => $item) {
                $list[] = [
                    'visitorid' => $visitorid,
                    'avatar'    => $default_avatar,
                    'app_title' => $item['app_title'],
                    'showHot'   => false,
                    'ip'        => $item['ip'],
                    'app'       => $item['app'],
                    'time'      => $item['time'],
                    'id'        => $item['id'],
                    'transfer'  => false
                    // 'name'      => ''
                ];
            }
            $result = [];
            $result['type'] = 'load';
            $result['list'] = $list;
            $result['uid'] = $_SESSION['uid'];
            Gateway::sendToCurrentClient($this->result(200, 'success', $result));
            unset($result);
            unset($list);
        } else {
            $result = [
                'type'  => 'chat',
                'uid'   => $_SESSION['uid']
            ];
            Gateway::sendToCurrentClient($this->result(200, 'success', $result));
            unset($result);
        }
    }

    /**
     * 会话转移
     *
     * @param array $data
     * @return void
     */
    public function transfer($data)
    {
        if (!isset($data['visitor']) || empty($data['visitor']) || !isset($data['target']) || empty($data['target'])) {
            return Gateway::sendToCurrentClient($this->result(404, 'params faild'));
        }
        $nowTime = time();
        // 转移的目标客服组别
        $target = $data['target'];
        // 目标客服client_id
        // $target_client_id = Gateway::getClientIdByUid($target);
        // 游客client_id
        $visitor_client_id = Gateway::getClientIdByUid($data['visitor']);
        $visitor_client_id = $visitor_client_id[0];
        // 转换组别
        Gateway::joinGroup($visitor_client_id, $target);
        Gateway::leaveGroup($visitor_client_id, $_SESSION['uid']);
        // 获取游客session
        $visitor_session = Gateway::getSession($visitor_client_id);
        // 通知新客服
        $result = [];
        $result['id'] = $visitor_session['id'];
        $result['type'] = 'waiter_transfer';
        $result['ip'] = $visitor_session['ip'];
        $result['app'] = $visitor_session['app'];
        $result['app_title'] = $visitor_session['app_title'];
        $result['client_uid'] = $visitor_session['uid'];
        $result['avatar'] = $visitor_session['avatar'];
        $result['time'] = $nowTime;
        $result['msg'] = "{$_SESSION['userInfo']['account']} - {$_SESSION['userInfo']['nickname']} 转接客服已链接";
        Gateway::sendToUid($data['target'], $this->result(200, 'success', $result));
        unset($result);
        // 通知游客
        $result = [];
        $result['type'] = 'chat';
        $result['uid'] = $data['visitor'];
        $result['group'] = $data['target'];
        $userInfo = ChatWaiterModel::instance()->getInfo(['id' => code2id($data['target'])]);
        if ($userInfo) {
            $nickname = '【' . $userInfo['nickname'] . '】';
        } else {
            $nickname = '';
        }
        $result['msg'] = '转接客服' . $nickname . '为您服务';
        Gateway::sendToUid($data['visitor'], $this->result(200, 'success', $result));
        unset($result);
        // 通知当前客服
        $result = [];
        $result['type'] = 'transfer';
        $result['visitor'] = $data['visitor'];
        $result['msg'] = '当前会话已转接至客服' . $nickname;
        Gateway::sendToCurrentClient($this->result(200, 'success', $result));
        unset($result);
        // 新会话关系入库
        $chat_relation = ChatMessageRelationModel::instance()->record($visitor_session['app'], code2id($data['target']), $visitor_session['uid']);
        if ($chat_relation) {
            // 更新最后通信时间
            ChatMessageRelationModel::instance()->save(['near_time' => $nowTime], ['id' => $chat_relation]);
        }
        // 结束原会话关系
        $ori_chat_relation = ChatMessageRelationModel::instance()->record($visitor_session['app'], code2id($_SESSION['uid']), $visitor_session['uid']);
        if ($ori_chat_relation) {
            // 更新最后通信时间
            ChatMessageRelationModel::instance()->save(['near_time' => $nowTime], ['id' => $chat_relation]);
            $chat_content = json_encode(['type' => 'tips', 'content' => "当前会话已转接至客服{$nickname}"], JSON_UNESCAPED_UNICODE);
            ChatMessageModel::instance()->record($ori_chat_relation, $chat_content);
        }
    }

    /**
     * 返回结果集
     *
     * @param integer $code
     * @param string $message
     * @param array $data
     * @param boolean $toJson
     * @return string
     */
    public function result($code, $message, $data = [], $toJson = true)
    {
        $data = [
            'code'  => $code,
            'msg'   => $message,
            'data'  => $data
        ];
        return $toJson ? json_encode($data, JSON_UNESCAPED_UNICODE) : $data;
    }
}
